不定參數,Variadic Macros
從手冊上看來,https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
Variadic macros are a new feature in C99. GNU CPP has supported them for a long time, but only with a named variable argument (‘args...’, not ‘...’ and __VA_ARGS__).
這是C99訂的功能,CNU CPP 已支援很長一段時間,只是它支援的型式是‘args...’。
為什麼選3個點**...** ,而不是2個點,或4個點呢?就上了年紀的人來說,真是很難接受。
而__VA_ARGS__,為什麼是前後兩底線__,中間一底線_呢?同樣很難理解,萬一老花眼,沒看仔細,不是找個錯,找大半天嗎?
手冊的例子,
如果你定義一個巨集,
#define eprintf(...) fprintf (stderr, __VA_ARGS__)
當你的程式
寫
eprintf ("%s:%d: ", input_file, lineno),
則前處理器會把這段CODE展開成
fprintf (stderr,"%s:%d: ", input_file, lineno)
而剛才那句巨集,也可寫成
#define eprintf(args...) fprintf (stderr, args)
比較
#define eprintf(...) fprintf (stderr, __VA_ARGS__)
如果USER實在看__VA_ARGS__不順眼。
所以呢,... 是宣告,對應__VA_ARGS__,
args...也是宣告,對應args。
...出現在參數的宣告,不能放在函數裏。
再來是一種特殊的情況,
#define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__)
當USER
寫
eprintf ("success!\n")
會展開成 ==> fprintf(stderr, "success!\n", );(展開的式子中,固定有兩個逗點,USER只傳一個參數,會多一個逗點出來)
這種多一個逗點的情況,你可以用
##__VA_ARGS__來去逗點,
#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
這樣當USER寫
eprintf ("success!\n")
==> fprintf(stderr, "success!\n");
不會再出現多一個逗點。
小結:這是筆者學其他語言少有的經驗,覺得不自然,有些彆扭,不知道其他學習者會不會有這樣感覺,在C99標準中,
定這些保留字,雖然非常非常的實用(偷懶的想,幾乎有用到參數的地方,都直接這樣寫了!!),卻要遵守規定,才能偷到懶。